/*
 * Copyright (C) 2011 Young,Fey <fey.young@gmail.com>
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */

package com.youngfey.sqlite
import groovy.util.logging.*
import groovy.transform.*
import static com.youngfey.sqlite.DataType.*

/**
 * 用于表述表列
 * @author Young,Fey <fey.young@gmail.com>
 */
@Log
class Column {
    /**
     * 构造新的Column
     * @param name 列名
     * @param nullable 是否可为空，默认值NULL值代表不明
     * @param autoIncrement 是否为自增列，默认值为NULL。注意在SQLite中，可以认为
     * 自增与单值域主键相同
     * @param type 列的类型
     */
    def Column(String name, Boolean nullable = null, Boolean autoIncrement = null,
            DataType type = null) {
        verify name
        this.name = name
        this.autoIncrement = autoIncrement
        this.nullable = autoIncrement ? false : nullable
        setType(autoIncrement ? INTEGER : type)
    }

    /**
     * 设定列数据类型，但不得为DataType.NULL型
     */
    void setType(DataType type) {
        if(type == NULL) {
            log.warning "Column Type is 'NULL': $name"
            this.type = DYNAMIC
        } else {
            this.type = type
        }
    }

    private verify = { String name ->
        assert name, "name couldn't be null or empty"
        assert name.size() <= 30 //此处并非SQLite限制，主要是为了通用性和规范性考虑
        //TODO: 使用正则表达式验证列名
    }

    //推测DLL语句
    private String genStmt() {
        if(autoId && name == 'id') return 'id INTEGER PRIMARY KEY'
        autoIncrement ?
        "$name INTEGER PRIMARY KEY" :
        "$name$typeStmt${ nullable == false ? ' NOT NULL' : '' }" 
    }

    private getTypeStmt() {
        type == null || type == DYNAMIC ? '' : " $type"
    }

    /**
     * 列名称相同则视为相等
     */
    boolean equal(obj) {
        obj && obj instanceof Column && obj.name == name
    }
    int hashCode() { name.hashCode() }

    final String name
    Boolean nullable
    Boolean autoIncrement
    DataType type
    
    /**
     * 是否自动将id列视为自增主键处理
     */
    boolean autoId = true
}

